package com.jeehentor.generate.generate.fileGenrate;

import com.alibaba.fastjson2.JSONObject;
import com.jeehentor.common.exception.HentorException;
import com.jeehentor.generate.dto.GenerateFileDTO;
import com.jeehentor.generate.entity.SysGenModel;
import com.jeehentor.generate.entity.SysGenModelField;
import com.jeehentor.generate.utils.CamelCaseUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

/**
 * 前端代码生成
 */
@Slf4j
public class VueFileGenerate extends AbstractFileGenerate{

    @Override
    public List<String> generate(GenerateFileDTO generateFileDTO) {
        //固定路径
        String tempPath = generateFileDTO.getModuleName()+".vue.";
        ArrayList<String> pathList = new ArrayList<>();
        //api文件
        pathList.add(generateApi(generateFileDTO,tempPath));
        //Write文件生成
        pathList.add(generateWrite(generateFileDTO,tempPath));
        //Detail文件生成
        pathList.add(generateDetail(generateFileDTO,tempPath));
        //index文件生成
        pathList.add(generateIndex(generateFileDTO,tempPath));
        return pathList;
    }


    /**
     * index文件生成
     * @return
     */
    private String generateIndex(GenerateFileDTO generateFileDTO,String tempPath){
        SysGenModel sysGenModel = generateFileDTO.getSysGenModel();
        List<SysGenModelField> fieldList = generateFileDTO.getFieldList();
        VelocityEngine velocityEngine = generateFileDTO.getVelocityEngin();
        //全路径
        String path = (tempPath).replace(".", "/");;
        //entity文件名
        Template template = velocityEngine.getTemplate("templates/elementPlus/Index.vm");
        VelocityContext context = new VelocityContext();

        List<HashMap<String, Object>> fields = new ArrayList<>();
        fieldList.stream().filter(x->!"id".equals(x.getFieldName())).sorted(Comparator.comparing(SysGenModelField::getSortOrder)).forEachOrdered(x->{
            HashMap<String, Object> field = createField(x);
            fields.add(field);
        });
        context.put("fields", fields);
        List<HashMap<String, Object>> searchFields = new ArrayList<>();
        fieldList.stream().filter(x->"1".equals(x.getIsQuery())).sorted(Comparator.comparing(SysGenModelField::getSortOrder)).forEachOrdered(x->{
            HashMap<String, Object> field = createField(x);
            searchFields.add(field);
        });
        context.put("searchFields", searchFields);
        List<HashMap<String, Object>> showFields = new ArrayList<>();
        fieldList.stream().filter(x->"1".equals(x.getIsShow())).sorted(Comparator.comparing(SysGenModelField::getSortOrder)).forEachOrdered(x->{
            HashMap<String, Object> field = createField(x);
            showFields.add(field);
        });
        context.put("showFields", showFields);
        List<HashMap<String, Object>> formFields = new ArrayList<>();
        fieldList.stream().filter(x->"1".equals(x.getIsForm())).sorted(Comparator.comparing(SysGenModelField::getSortOrder)).forEachOrdered(x->{
            HashMap<String, Object> field = createField(x);
            formFields.add(field);
        });
        context.put("formFields", formFields);
        context.put("entityNameLower", CamelCaseUtil.underscoreToCamelCase(sysGenModel.getTableName(),false));
        File  directory = new File(path);
        if (!directory.exists()) {
            boolean mkdirs = directory.mkdirs();
            if(!mkdirs){
                throw new HentorException(path+"目录创建失败！");
            }
        }
        String filePath = path+"/"+CamelCaseUtil.underscoreToCamelCase(sysGenModel.getTableName(),true)+".vue";
        try (Writer writer = new FileWriter(filePath)) {
            template.merge(context, writer);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.info(String.format("vue:index文件生成成功，路径%s",filePath));
        return filePath;
    }

    /**
     * Write文件生成
     * @return
     */
    private String generateWrite(GenerateFileDTO generateFileDTO,String tempPath){
        SysGenModel sysGenModel = generateFileDTO.getSysGenModel();
        List<SysGenModelField> fieldList = generateFileDTO.getFieldList();
        VelocityEngine velocityEngine = generateFileDTO.getVelocityEngin();
        //全路径
        String path = (tempPath+".components").replace(".", "/");
        //entity文件名
        Template template = velocityEngine.getTemplate("templates/elementPlus/Write.vm");
        VelocityContext context = new VelocityContext();
        List<HashMap<String, Object>> formFields = new ArrayList<>();
        fieldList.stream().filter(x->"1".equals(x.getIsForm())).sorted(Comparator.comparing(SysGenModelField::getSortOrder)).forEachOrdered(x->{
            HashMap<String, Object> field = createField(x);
            formFields.add(field);
            Object formModuleOption = field.get("formModuleOption");
            if(formModuleOption != null){
                JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(formModuleOption));
                Object moduleType = jsonObject.get("moduleType");
                if(moduleType != null && "2".equals(moduleType.toString())){
                    //如果是字典，则需要导入字典api
                    context.put("dictApi", "import { getDictItemByCodeApi } from '@/api/dict'");
                }else if (moduleType != null && "3".equals(moduleType.toString())){
                    context.put("modelApi", "import { selectByModelApi } from '@/api/sysGenPage'");
                }
            }
        });
        context.put("formFields", formFields);
        List<HashMap<String, Object>> requiredFields = new ArrayList<>();
        fieldList.stream().filter(x->"1".equals(x.getIsRequired())).sorted(Comparator.comparing(SysGenModelField::getSortOrder)).forEachOrdered(x->{
            HashMap<String, Object> field = createField(x);
            requiredFields.add(field);
        });
        context.put("requiredFields", requiredFields);
        context.put("entityNameLower", CamelCaseUtil.underscoreToCamelCase(sysGenModel.getTableName(),false));
        File  directory = new File(path);
        if (!directory.exists()) {
            boolean mkdirs = directory.mkdirs();
            if(!mkdirs){
                throw new HentorException(path+"目录创建失败！");
            }
        }
        String filePath = path+"/Write.vue";
        try (Writer writer = new FileWriter(filePath)) {
            template.merge(context, writer);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.info(String.format("vue:Write文件生成成功，路径%s",filePath));
        return filePath;
    }

    /**
     * Detail文件生成
     * @return
     */
    private String generateDetail(GenerateFileDTO generateFileDTO,String tempPath){
        SysGenModel sysGenModel = generateFileDTO.getSysGenModel();
        List<SysGenModelField> fieldList = generateFileDTO.getFieldList();
        VelocityEngine velocityEngine = generateFileDTO.getVelocityEngin();
        //全路径
        String path = (tempPath+".components").replace(".", "/");
        //entity文件名
        Template template = velocityEngine.getTemplate("templates/elementPlus/Detail.vm");
        VelocityContext context = new VelocityContext();
        List<HashMap<String, Object>> formFields = new ArrayList<>();
        fieldList.stream().filter(x->"1".equals(x.getIsForm())).sorted(Comparator.comparing(SysGenModelField::getSortOrder)).forEachOrdered(x->{
            HashMap<String, Object> field = createField(x);
            formFields.add(field);
        });
        context.put("formFields", formFields);
        List<HashMap<String, Object>> requiredFields = new ArrayList<>();
        fieldList.stream().filter(x->"1".equals(x.getIsRequired())).sorted(Comparator.comparing(SysGenModelField::getSortOrder)).forEachOrdered(x->{
            HashMap<String, Object> field = createField(x);
            requiredFields.add(field);
        });
        context.put("requiredFields", requiredFields);
        context.put("entityNameLower", CamelCaseUtil.underscoreToCamelCase(sysGenModel.getTableName(),false));
        File  directory = new File(path);
        if (!directory.exists()) {
            boolean mkdirs = directory.mkdirs();
            if(!mkdirs){
                throw new HentorException(path+"目录创建失败！");
            }
        }
        String filePath = path+"/Detail.vue";
        try (Writer writer = new FileWriter(filePath)) {
            template.merge(context, writer);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.info(String.format("vue:Detail文件生成成功，路径%s",filePath));
        return filePath;
    }


    /**
     * api文件生成
     * @return
     */
    private String generateApi(GenerateFileDTO generateFileDTO,String tempPath){
        SysGenModel sysGenModel = generateFileDTO.getSysGenModel();
        VelocityEngine velocityEngine = generateFileDTO.getVelocityEngin();
        //全路径
        String path = (tempPath+ ".api."+CamelCaseUtil.underscoreToCamelCase(sysGenModel.getTableName(),false)).replace(".", "/");
        //entity文件名
        Template template = velocityEngine.getTemplate("templates/elementPlus/Api.vm");
        VelocityContext context = new VelocityContext();
        context.put("entityNameLower", CamelCaseUtil.underscoreToCamelCase(sysGenModel.getTableName(),false));
        File  directory = new File(path);
        if (!directory.exists()) {
            boolean mkdirs = directory.mkdirs();
            if(!mkdirs){
                throw new HentorException(path+"目录创建失败！");
            }
        }
        String filePath = path+"/index.ts";
        try (Writer writer = new FileWriter(filePath)) {
            template.merge(context, writer);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.info(String.format("vue:api文件生成成功，路径%s",filePath));
        return filePath;
    }


    private static HashMap<String, Object> createField(SysGenModelField sysGenModelField) {
        HashMap<String, Object> field = new HashMap<>(7);
        field.put("modelId", sysGenModelField.getModelId());
        field.put("formModule", sysGenModelField.getFormModule());
        field.put("searchModule", sysGenModelField.getSearchModule());
        field.put("isRequired", "1".equals(sysGenModelField.getIsRequired()));
        field.put("name", CamelCaseUtil.underscoreToCamelCase(sysGenModelField.getFieldName(), false));
        field.put("description", sysGenModelField.getRemarks());
        field.put("columnWidth", sysGenModelField.getColumnWidth());
        field.put("searchSpan", sysGenModelField.getSearchSpan());
        field.put("formModuleOption", JSONObject.parseObject(sysGenModelField.getFormModuleOption()));
        return field;
    }
}
